package net.sxnic.workflow.node;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sxinfo.core.dao.hibernate3.HcUtils;
import net.sxinfo.core.dao.hibernate3.HibernateCriteria;
import net.sxinfo.core.spring25.Dao;
import net.sxinfo.core.spring25.DefaultManager;
import net.sxnic.comm.utils.CommUtils;
import net.sxnic.ugr.UgrConstant;
import net.sxnic.ugr.context.AppContext;
import net.sxnic.ugr.user.User;
import net.sxnic.ugr.utils.UgrManagerUtils;
import net.sxnic.workflow.node.dao.NodeDao;
import net.sxnic.workflow.pd.Pd;
import net.sxnic.workflow.pd.PdManager;
import net.sxnic.workflow.task.util.TaskUtils;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("nodeManager")
public class DefaultNodeManager extends DefaultManager<Node, NodeDao, String> implements NodeManager {
	
	private static Logger logger = LoggerFactory.getLogger(DefaultNodeManager.class);

	@Autowired
	private NodeDao nodeDao;

	@Autowired
	private PdManager pdManager;

	@Override
	protected Dao<Node, String> getEntityDao() {
		return nodeDao;
	}

	@Override
	public Node findByPdName(Pd pd, String name) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("pd", pd);
		map.put("name", name);
		HibernateCriteria hc = HcUtils.creat(map, null);
		List<Node> list = nodeDao.getByCriteria(hc);
		
		if(list==null||list.size()==0){
			logger.error("在流程:{}，中查找节点:{}失败",pd.getName(),name);
			return null;
		}
		
		return list.get(0);
	}

	@Override
	public List<Node> findNextNodes(Pd pd, String currNodeName) {
		Node currNode = findByPdName(pd, currNodeName);
		List<Node> list = new ArrayList<Node>();

		String[] node_s = StringUtils.split(currNode.getNextNode(), ",");
		for (String n : node_s) {
			list.add(findByPdName(pd, n));
		}

		return list;
	}

	@Override
	public Node findStartNode(String pdName) {
		Pd pd = pdManager.findLatestPdByName(pdName);
		return findStartNode(pd);
	}

	@Override
	public Node findStartNode(Pd pd) {
		List<Node> nodes = nodeDao.findBy("pd", pd);
		for (Node n : nodes) {
			if ("start".equals(n.getCate())) {
				return n;
			}
		}
		return null;
	}

	@Override
	public List<Node> findNextNodes(String pdName, String currNodeName) {
		Pd pd = pdManager.findLatestPdByName(pdName);
		return findNextNodes(pd, currNodeName);
	}

	@Override
	public Node findByPdName(String pdName, String name) {
		return findByPdName(pdManager.findLatestPdByName(pdName), name);
	}

	@Override
	public Node findByProcessNameNodeName(String processName, String nodeName) {
		return findByPdName(pdManager.findLatestPdByName(processName), nodeName);
	}

	@Override
	public String[] findAssigneeByProcessNode(String pdName, String currNodeName) {
		// 找到 当前node
		Node currNode = this.findByPdName(pdName, currNodeName);

		// 整合所有后续node的assignee定义
		// 用户排名 用户名的Map
		Map<String, String> assignee = new LinkedHashMap<String, String>();
		User user;

		String assigneeDef = currNode.getNextNode();

		// users:gal,sgy;groups:000,001;roles:office,docManager;special:chuanyue
		// 把上面的内容转换按分号隔开
		String[] assignee_defs = StringUtils.split(assigneeDef, ";");
		for (String a : assignee_defs) {
			// 把users:gal,sgy 分开，即把承办人类型和承办人具体定义分开处理
			String before = StringUtils.substringBefore(a, ":");
			String after = StringUtils.substringAfter(a, ":");

			// 特殊的接收人
			if (before.equals("specail")) {
				//
				String[] temp1 = StringUtils.split(after, TaskUtils.NEXTASSIGNEES_SEPARATOR);
				for (String t1 : temp1) {
					if (t1.trim().equals(NodeConfig.DEFAULTASSIGNEE_CHUSHI)) {
						// 处室
						return new String[] { NodeConfig.DEFAULTASSIGNEE_CHUSHI };
					} else if (t1.trim().equals(NodeConfig.DEFAULTASSIGNEE_CHUANYUE)) {
						// 传阅
						return new String[] { NodeConfig.DEFAULTASSIGNEE_CHUANYUE };
					} else if (t1.trim().equals(NodeConfig.DEFAULTASSIGNEE_CHUZHANG)) {
						// 查询当前用户所在处室的 处长
						user = UgrManagerUtils.getUserManager().getChiefByUsername(AppContext.getUserName());
						// add to assignee set
						assignee.put(UgrConstant.USER_ORDER_MAP.get(user.getUsername()), user.getUsername());

					}  else if (t1.trim().equals(NodeConfig.DEFAULTASSIGNEE_DRAFTER)) {
						// 发起人
						return new String[] { NodeConfig.DEFAULTASSIGNEE_DRAFTER};
					}
				}
			}

			if (before.equals("users")) {
				// users
				String[] temp1 = StringUtils.split(after, TaskUtils.NEXTASSIGNEES_SEPARATOR);
				// indexs
				for (String t1 : temp1) {
					user = UgrManagerUtils.getUserManager().getUserByUsername(t1);
					// add to assignee set
					assignee.put(String.valueOf(user.getUserOrder()), user.getUsername());
				}
			}
			if (before.equals("roles")) {
				// roles
				String[] temp1 = StringUtils.split(after, TaskUtils.NEXTASSIGNEES_SEPARATOR);
				for (String t1 : temp1) {
					List<User> users = UgrManagerUtils.getAuthorizationManager().getUsersInRole(t1);
					for (User u : users) {
						// add to assignee set
						assignee.put(String.valueOf(u.getUserOrder()), u.getUsername());
					}
				}
			}
			if (before.equals("groups")) {
				// group
				String[] temp1 = StringUtils.split(after, TaskUtils.NEXTASSIGNEES_SEPARATOR);

				for (String t1 : temp1) {
					List<User> users = UgrManagerUtils.getAuthorizationManager().getUsersInGroup(t1);
					for (User u : users) {
						// add to assignee set
						assignee.put(String.valueOf(u.getUserOrder()), u.getUsername());
					}
				}
			}

		}

		if (assignee == null || assignee.size() == 0) {
			return null;
		}

		// 排序
		String[] temp = new String[assignee.size()];
		String[] temp1 = new String[assignee.size()];

		temp = CommUtils.SettoArray(assignee.keySet());
		Arrays.sort(temp);

		int i = 0;
		for (String ss : temp) {
			temp1[i] = assignee.get(ss);
			i++;
		}

		return temp1;
	}

	@Override
	public String findtNextAssigneeByNode(Node node) {
		try {
			// set 是节点set
			Set<String> set = new LinkedHashSet<String>();
			set = CommUtils.ArraytoSet(StringUtils.split(node.getNextNode(), ","));

			if (set == null || set.size() == 0) {
				return "";
			}

			// map内容
			// 批阅-String[]{htc,wh,qzd,wxp}
			// 承办-String[]{sgy,zhl,gjl,zkj}
			Map<String, String[]> map = new LinkedHashMap<String, String[]>();

			for (String nodeName : set) {
				map.put(nodeName, findAssigneeByProcessNode(node.getPd().getName(), nodeName));
			}

			return TaskUtils.treatMaptoNextAssignees(map);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(node.getName()+"===findtNextAssigneeByNode==="+e.toString());
			return "";
		}
	}

}
